const fs = require('fs');
const path = require('path');
const { customRequire } = require('../utils.js');
const config = require('../config');
const manifest = require('../manifest.json');
const { log, error, cleanupModuleData } = require('../utils.js');
const { formatDateToEnglish } = require('../utils/dateFormatter.js');
const pathUtils = require('../utils/path-utils');

// 设置全局错误处理器
process.on('uncaughtException', (err) => {
    console.error('未捕获的异常:', err);
    console.error('错误堆栈:', err.stack);
    error('未捕获的异常: ' + err.message, err);
    log('发生未捕获的异常: ' + err.message);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的Promise拒绝:', reason);
    if (reason instanceof Error) {
        console.error('错误堆栈:', reason.stack);
        error('未处理的Promise拒绝: ' + reason.message, reason);
        log('发生未处理的Promise拒绝: ' + reason.message);
    } else {
        error('未处理的Promise拒绝: ' + reason);
        log('发生未处理的Promise拒绝: ' + reason);
    }
});

// 导入外部模块
log('正在导入playwright模块...');
const { chromium } = customRequire('playwright');
log('正在导入fs模块...');

// 记录配置信息
log(`插件版本: ${manifest.version}`);
log(`配置加载完成: 浏览器超时=${config.browser.timeout}ms, 重试次数=${config.retry.maxRetries}`);

// 目标技术委员会列表
const TARGET_TCS = [
    'CEN/TC 33', 'CEN/TC 49', 'CEN/TC 52', 'CEN/TC 67', 'CEN/TC 93',
    'CEN/TC 114', 'CEN/TC 136', 'CEN/TC 158', 'CEN/TC 162', 'CEN/TC 163',
    'CEN/TC 194', 'CEN/TC 207', 'CEN/TC 217', 'CEN/TC 252', 'CEN/TC 255',
    'CEN/TC 333', 'CEN/TC 355', 'CEN/TC 364', 'CEN/TC 369', 'CEN/TC 402'
];

// CEN网站URL
const CEN_URL = 'https://standards.cencenelec.eu/dyn/www/f?p=CEN:84:0:::::';

// 全局变量，用于存储当前浏览器实例，以便在中断时关闭
let currentBrowser = null;

class CenScraper {
    constructor() {
        this.browser = null;
        this.page = null;
        this.context = null;
        this.isRunning = false;
        this.filteredData = [];
    }

    // 初始化浏览器
    async initBrowser(headless = true, signal = null) {
        try {
            log('启动浏览器...');
            log('浏览器配置: ' + (!headless ? '显示模式' : '隐藏模式') + ', 超时: ' + config.browser.timeout + 'ms');
            
            this.browser = await chromium.launch({
                headless: headless,
                timeout: config.browser.timeout,
                args: ['--start-maximized', '--disable-features=IsolateOrigins,site-per-process'],
                executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
            });
            
            log('浏览器启动成功，使用' + (!headless ? '显示模式' : '隐藏模式'));
            
            // 存储浏览器实例，以便在中断时关闭
            currentBrowser = this.browser;
            
            // 如果信号存在，添加中断处理
            if (signal) {
                log('已设置中断信号处理器', 'info');
                signal.addEventListener('abort', async () => {
                    log('收到中断信号，正在关闭浏览器...', 'warning');
                    if (currentBrowser) {
                        try {
                            await currentBrowser.close();
                            log('浏览器已关闭（由中断信号触发）', 'info');
                        } catch (err) {
                            console.error('关闭浏览器时出错:', err);
                            log(`关闭浏览器时出错: ${err.message}`, 'error');
                        }
                        currentBrowser = null;
                    }
                });
            }
            
            this.context = await this.browser.newContext({ 
                viewport: null, 
                userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' 
            });
            log('创建浏览器上下文成功', 'info');
            
            this.page = await this.context.newPage();
            log('创建新页面成功', 'info');
            
            // 设置默认超时时间
            this.page.setDefaultTimeout(config.browser.defaultTimeout);
            
            console.log('浏览器初始化成功');
            return true;
        } catch (error) {
            console.error('浏览器初始化失败:', error);
            error('浏览器初始化失败: ' + error.message, error);
            throw error;
        }
    }

    // 获取CEN标准数据
    async fetchCenData(progressCallback, signal = null) {
        if (!this.browser || !this.page) {
            throw new Error('浏览器未初始化');
        }

        try {
            this.isRunning = true;
            this.filteredData = [];
            
            // 检查是否已经被中止
            if (signal && signal.aborted) {
                log('任务已被用户取消', 'warning');
                throw new Error('任务已被用户取消');
            }
            
            // 导航到CEN网站
            if (progressCallback) progressCallback(10, '正在访问CEN网站...');
            log('正在访问CEN网站: ' + CEN_URL, 'info');
            
            await this.page.goto(CEN_URL, { 
                waitUntil: 'networkidle',
                timeout: config.browser.timeout 
            });
            
            if (progressCallback) progressCallback(30, '页面加载完成，正在查找表格...');
            log('页面加载完成，正在查找表格...', 'info');
            
            // 等待包含数据的表格加载
            await this.page.waitForSelector('table.dashlist tbody tr', { timeout: config.browser.defaultTimeout });
            log('找到包含数据的表格，开始解析数据...', 'info');
            
            if (progressCallback) progressCallback(50, '正在解析表格数据...');
            
            // 提取表格数据
            const tableData = await this.page.evaluate(() => {
                // 查找包含tbody的表格（第二个table.dashlist）
                const tables = document.querySelectorAll('table.dashlist');
                let table = null;
                for (let t of tables) {
                    if (t.querySelector('tbody tr')) {
                        table = t;
                        break;
                    }
                }
                if (!table) return [];
                
                const rows = table.querySelectorAll('tbody tr');
                const data = [];
                
                rows.forEach(row => {
                    const cells = row.querySelectorAll('td');
                    if (cells.length >= 4) {
                        // 提取标准编号和链接
                        const referenceCell = cells[0];
                        const referenceLink = referenceCell.querySelector('a');
                        const reference = referenceLink ? referenceLink.textContent.trim() : referenceCell.textContent.trim();
                        const detailUrl = referenceLink ? referenceLink.href : null;
                        
                        // 提取其他信息
                        const title = cells[1].textContent.trim();
                        const technicalBody = cells[2].textContent.trim();
                        const publicationDate = cells[3].textContent.trim();
                        
                        data.push({
                            reference,
                            title,
                            technicalBody,
                            publicationDate,
                            detailUrl
                        });
                    }
                });
                
                return data;
            });
            
            if (progressCallback) progressCallback(70, '正在筛选目标技术委员会数据...');
            
            // 筛选目标TC的数据
            this.filteredData = this.filterTargetTCs(tableData);
            
            if (progressCallback) progressCallback(80, '正在获取详细信息...');
            
            // 为每个筛选出的记录获取详细信息
            await this.fetchDetailedInfo(this.filteredData, progressCallback, signal);
            
            if (progressCallback) progressCallback(90, '数据处理完成...');
            
            console.log(`成功获取 ${tableData.length} 条记录，筛选出 ${this.filteredData.length} 条目标TC记录`);
            
            if (progressCallback) progressCallback(100, `筛选完成，共找到 ${this.filteredData.length} 条记录`);
            
            return this.filteredData;
            
        } catch (error) {
            console.error('获取CEN数据时发生错误:', error);
            throw error;
        } finally {
            this.isRunning = false;
        }
    }

    // 筛选目标技术委员会的数据
    filterTargetTCs(data) {
        return data.filter(item => {
            return TARGET_TCS.some(tc => 
                item.technicalBody === tc
            );
        });
    }

    // 获取每个记录的详细信息
    async fetchDetailedInfo(data, progressCallback, signal = null) {
        if (!data || data.length === 0) {
            log('没有需要获取详细信息的数据', 'info');
            return;
        }

        log(`开始获取 ${data.length} 条记录的详细信息...`, 'info');
        
        for (let i = 0; i < data.length; i++) {
            const item = data[i];
            
            // 检查是否已被中止
            if (signal && signal.aborted) {
                log('任务已被用户取消', 'warning');
                throw new Error('任务已被用户取消');
            }
            
            if (!item.detailUrl) {
                log(`记录 ${item.reference} 没有详情链接，跳过`, 'warning');
                item.dateOfWithdrawal = '';
                item.supersedes = '';
                continue;
            }
            
            try {
                log(`正在获取 ${item.reference} 的详细信息... (${i + 1}/${data.length})`, 'info');
                
                // 在新标签页中打开详情页面
                const detailPage = await this.context.newPage();
                
                try {
                    await detailPage.goto(item.detailUrl, { 
                        waitUntil: 'networkidle',
                        timeout: config.browser.timeout 
                    });
                    
                    // 提取DOW和Supersedes信息
                    const detailInfo = await detailPage.evaluate(() => {
                        let dateOfWithdrawal = '';
                        let supersedes = '';
                        
                        // 查找date of Withdrawal (DOW) (5)
                        const dowRows = document.querySelectorAll('tr');
                        for (let row of dowRows) {
                            const th = row.querySelector('th.detail');
                            if (th && th.textContent.includes('date of Withdrawal (DOW) (5)')) {
                                const td = row.querySelector('td');
                                if (td) {
                                    dateOfWithdrawal = td.textContent.trim();
                                }
                                break;
                            }
                        }
                        
                        // 查找Supersedes
                        for (let row of dowRows) {
                            const th = row.querySelector('th.detail');
                            if (th && th.textContent.includes('Supersedes')) {
                                const td = row.querySelector('td');
                                if (td) {
                                    supersedes = td.textContent.trim();
                                    // 移除&nbsp;等空白字符
                                    supersedes = supersedes.replace(/\u00A0/g, '').trim();
                                }
                                break;
                            }
                        }
                        
                        return { dateOfWithdrawal, supersedes };
                    });
                    
                    // 将提取的信息添加到原始数据中
                    item.dateOfWithdrawal = detailInfo.dateOfWithdrawal || '';
                    item.supersedes = detailInfo.supersedes || '';
                    
                    // 在控制台打印每条记录的信息
                    console.log(`记录 ${i + 1}: ${item.reference}`);
                    console.log(`  标题: ${item.title}`);
                    console.log(`  技术委员会: ${item.technicalBody}`);
                    console.log(`  发布日期: ${item.publicationDate}`);
                    console.log(`  撤销日期 (DOW): ${item.dateOfWithdrawal || '无'}`);
                    console.log(`  替代标准 (Supersedes): ${item.supersedes || '无'}`);
                    console.log(`  详情链接: ${item.detailUrl}`);
                    console.log('---');
                    
                    log(`成功获取 ${item.reference} 的详细信息`, 'info');
                    
                } finally {
                    await detailPage.close();
                }
                
            } catch (error) {
                console.error(`获取 ${item.reference} 详细信息时出错:`, error);
                log(`获取 ${item.reference} 详细信息时出错: ${error.message}`, 'error');
                
                // 设置默认值
                item.dateOfWithdrawal = '';
                item.supersedes = '';
            }
            
            // 更新进度
            if (progressCallback) {
                const progress = 80 + Math.floor((i + 1) / data.length * 10);
                progressCallback(progress, `已处理 ${i + 1}/${data.length} 条记录`);
            }
            
            // 添加延迟以避免请求过于频繁
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
        
        log(`完成所有 ${data.length} 条记录的详细信息获取`, 'info');
    }

    // 停止爬取
    async stop() {
        this.isRunning = false;
        log('正在停止CEN数据获取...', 'warning');
        
        try {
            if (this.page) {
                await this.page.close();
                this.page = null;
                log('页面已关闭', 'info');
            }
            
            if (this.context) {
                await this.context.close();
                this.context = null;
                log('浏览器上下文已关闭', 'info');
            }
            
            if (this.browser) {
                await this.browser.close();
                this.browser = null;
                currentBrowser = null;
                log('浏览器已关闭', 'info');
            }
        } catch (error) {
            console.error('关闭浏览器时出错:', error);
            log(`关闭浏览器时出错: ${error.message}`, 'error');
        }
        
        log('CEN数据获取已停止', 'info');
    }

    // 获取筛选后的数据
    getFilteredData() {
        return this.filteredData;
    }

    // 导出数据为CSV格式
    exportToCSV() {
        if (!this.filteredData || this.filteredData.length === 0) {
            throw new Error('没有可导出的数据');
        }

        const headers = ['Standard reference', 'Title', 'Technical body', 'Date of Publication', 'Date of Withdrawal (DOW)', 'Supersedes', 'Detail URL'];
        let csvContent = headers.join(',') + '\n';
        
        this.filteredData.forEach(item => {
            const row = [
                `"${item.reference}"`,
                `"${item.title}"`,
                `"${item.technicalBody}"`,
                `"${item.publicationDate}"`,
                `"${item.dateOfWithdrawal || ''}"`,
                `"${item.supersedes || ''}"`,
                `"${item.detailUrl || ''}"`
            ];
            csvContent += row.join(',') + '\n';
        });
        
        return csvContent;
    }

    // 导出数据为JSON格式
    exportToJSON() {
        return JSON.stringify({
            region: 'Europe',
            standard: standardNumber,
            standardName: title,
            dateOfPublication: publicationDate,
            brief: '',
            url: '',
            
            exportTime: new Date().toISOString(),
            // targetTCs: TARGET_TCS,
            totalRecords: this.filteredData.length,
            data: this.filteredData
        }, null, 2);
    }
}

// 导出模块
module.exports = {
    CenScraper,
    TARGET_TCS,
    CEN_URL
};

// 全局变量用于中断控制
let abortController = null;

// 主要的CEN数据获取函数
async function scrapeCenUpdates(isHeadless, signal) {
    log(`开始执行 CEN 标准更新数据抓取任务`, 'info');
    log(`目标技术委员会: ${TARGET_TCS.length} 个`, 'info');
    
    // 检查是否已经被中止
    if (signal && signal.aborted) {
        log('任务已被用户取消', 'warning');
        throw new Error('任务已被用户取消');
    }
    
    const scraper = new CenScraper();
    
    try {
        // 初始化浏览器
        await scraper.initBrowser(!isHeadless, signal); // 注意：UI中显示模式对应headless=false
        
        // 获取数据
        const allData = await scraper.fetchCenData((progress, message) => {
            // 这里可以添加进度回调处理
            console.log(`进度: ${progress}% - ${message}`);
        }, signal);
        
        // 筛选目标TC数据
        const filteredData = scraper.filterTargetTCs(allData);
        
        log(`数据获取完成，共找到 ${allData.length} 条记录，筛选出 ${filteredData.length} 条目标TC记录`, 'success');
        
        // 保存数据到JSON文件
        if (filteredData.length > 0) {
            // 清理旧数据文件
            try {
                cleanupModuleData('cen');
            } catch (cleanupError) {
                log(`清理旧数据时出现警告: ${cleanupError.message}`, 'warning');
            }
            
            // 使用统一的数据路径管理
            const dataDir = pathUtils.getDataPath('cen');
            pathUtils.ensureDirectoryExists(dataDir);
            
            const filePath = path.join(dataDir, `cen_updates_${new Date().toISOString().slice(0, 10)}.json`);
            
            // 转换数据格式以符合用户要求
            const formattedData = filteredData.map(item => {
                // 构建brief字段：Standard reference + 空格 + supersedes + 空格 + Supersedes的值 + date of Withdrawal (DOW): + 空格 + Date of Withdrawal (DOW)的值
                let brief = item.reference || '';
                if (item.supersedes) {
                    brief += ` supersedes ${item.supersedes}`;
                }
                if (item.dateOfWithdrawal) {
                    brief += ` date of Withdrawal (DOW): ${item.dateOfWithdrawal}`;
                }
                
                return {
                    region: 'Europe',
                    standard: item.reference || '',
                    standardName: item.title || '',
                    dateOfPublication: formatDateToEnglish(item.publicationDate || ''),
                    brief: brief,
                    url: item.detailUrl || ''
                };
            });
            
            const jsonData = {
                exportTime: new Date().toISOString(),
                targetTCs: TARGET_TCS,
                totalRecords: filteredData.length,
                data: formattedData
            };
            
            fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2));
            log(`数据已保存到文件: ${filePath}`, 'success');
            
            // 额外稳健清理：再次删除同目录下除当前文件外的其他JSON，确保只保留最新结果
            try {
                const filesInDir = fs.readdirSync(dataDir);
                const currentFileName = path.basename(filePath);
                let removed = 0;
                filesInDir.forEach(fname => {
                    if (fname.endsWith('.json') && fname !== currentFileName) {
                        try {
                            fs.unlinkSync(path.join(dataDir, fname));
                            removed++;
                            log(`已额外删除旧数据文件: ${fname}`, 'info');
                        } catch (delErr) {
                            log(`额外删除旧文件失败 ${fname}: ${delErr.message}`, 'warning');
                        }
                    }
                });
                if (removed > 0) {
                    log(`目录清理完成，已额外删除 ${removed} 个旧JSON文件，仅保留: ${currentFileName}`, 'success');
                }
            } catch (postCleanupErr) {
                log(`额外目录清理出现问题: ${postCleanupErr.message}`, 'warning');
            }
        } else {
            log('没有找到符合条件的数据，未生成JSON文件', 'warning');
        }
        
        // 直接返回筛选后的数据数组，与ASTM保持一致
        return filteredData;
        
    } catch (error) {
        log(`CEN数据获取失败: ${error.message}`, 'error');
        throw error;
    } finally {
        // 确保浏览器被关闭
        await scraper.stop();
    }
}

// 带信号控制的运行函数
async function runWithSignal(signal, isHeadless) {
    try {
        const result = await scrapeCenUpdates(isHeadless, signal);
        
        if (signal && signal.aborted) {
            log('任务被用户取消', 'warning');
            return { success: false, message: '任务被用户取消' };
        }
        
        return result;
        
    } catch (error) {
        if (signal && signal.aborted) {
            log('任务被用户取消', 'warning');
            return { success: false, message: '任务被用户取消' };
        }
        
        log(`执行失败: ${error.message}`, 'error');
        throw error;
    }
}

// 主函数
async function main(isHeadless) {
    try {
        log('开始执行CEN标准更新数据获取...', 'info');
        
        const result = await scrapeCenUpdates(isHeadless);
        
        log('CEN标准更新数据获取完成', 'success');
        return result;
        
    } catch (error) {
        log(`执行失败: ${error.message}`, 'error');
        throw error;
    }
}

// 如果作为主模块运行
if (require.main === module) {
    // 从命令行参数获取headless设置
    const isHeadless = process.argv[2] === 'true' || process.argv[2] === true;
    console.log('CEN Core: 从命令行参数获取headless设置:', isHeadless);
    
    main(isHeadless).then(result => {
        console.log('CEN Core: 执行结果:', result);
        process.exit(0);
    }).catch(err => {
        console.error('CEN Core: 执行失败:', err);
        process.exit(1);
    });
} else {
    // 导出模块
    module.exports = main;
    module.exports.scrapeCenUpdates = scrapeCenUpdates;
    module.exports.runWithSignal = runWithSignal;
}